#pragma once

#include <stdint.h>
#include <list>
#include <mutex>
#include "uv.h"
#include "net_callback.h"

namespace rr {
namespace nio {

class EventLoop;

class EventAsync 
{
public:
    using Sptr = std::shared_ptr<EventAsync>;
    using PendingCallback = VoidCallback;
    using PendingCallbackList = std::list<PendingCallback>;
    using AsyncCloseCallback = std::function<void()>;
public:
    EventAsync(EventLoop* loop);
    ~EventAsync();

    int32_t Start();
    void Close(const AsyncCloseCallback& cb);
    int32_t submit(const PendingCallback &cb);

private:
    static void OnAsyncCb(uv_async_t* handle);
    void DoCallback();
    static void OnCloseCb(uv_handle_t* handle);
    void DoClose();

private:
    EventLoop *loop_;
    uv_async_t uv_async_{};
    AsyncCloseCallback close_cb_;
    std::mutex mutex_;
    PendingCallbackList pending_cbs;
};

} //namespace 
} //namespace 